package cn.com.cfae.iras.doc.analyze.components.integrity;

import cn.com.cfae.iras.doc.analyze.components.BaseComponent;
import cn.com.cfae.iras.doc.analyze.components.common.Constants;
import cn.com.cfae.iras.doc.analyze.components.beans.ComponentResult;
import cn.com.cfae.iras.doc.analyze.parse.QYZXUtils;
import cn.com.cfae.iras.doc.analyze.parse.SimilarAnalyser;
import cn.com.cfae.iras.doc.analyze.parse.kv.KVText;
import cn.com.cfae.iras.doc.analyze.parse.model.ExtractBizModel;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * Created by 佟媛媛 on 18/10/23.
 */

@Component("I1002")
@Scope("prototype")
public class I1002 extends BaseComponent {

    private static Logger log = LoggerFactory.getLogger(I1002.class);

    Gson gson = new GsonBuilder().create();




    @Override
    public List<ComponentResult> handlerM() {
        return common("M-3");
    }

    private List<ComponentResult> common(String catalogId){
        List<ComponentResult> list = new ArrayList<>();
        setCatalogId(catalogId);
//    stage: 发行阶段。"01"预评阶段，"02"发行阶段
//    exist: 01正确  02错误  03疑似
        if("01".equals(getStage())){
            list.add(fxdx(getCatalogId(),"FXTK","FXDX"));//发行对象
            list.add(xypjjg(getCatalogId(),"FXTK","XYPJJG"));//信用评级机构
            list.add(swts(getCatalogId(),"FXTK","SWTS"));//税务提示
            list.add(syfl(getCatalogId(),"FXTK","SYFL"));//适用法律
        }else if("02".equals(getStage())){
            list.add(fxdx(getCatalogId(),"FXTK","FXDX"));//发行对象
            list.add(cxfs(getCatalogId(),"FXTK","CXFS"));//承销方式
            list.add(fxfs(getCatalogId(),"FXTK","FXFS"));//发行方式
            list.add(dfjg(getCatalogId(),"FXTK","DFJG"));//兑付价格
            list.add(dffs(getCatalogId(),"FXTK","DFFS"));//兑付方式
            list.add(jzbjjd(getCatalogId(),"FXTK","JZBJJDJSZCJG"));//集中簿记建档系统技术支持机构
            list.add(xypjjg(getCatalogId(),"FXTK","XYPJJG"));//信用评级机构
            list.add(dbzk(getCatalogId(),"FXTK","DB"));//担保状况
            list.add(swts(getCatalogId(),"FXTK","SWTS"));//税务提示
            list.add(syfl(getCatalogId(),"FXTK","SYFL"));//适用法律
        }
        return list;
    }

    @Override
    public List<ComponentResult> handlerBM() {
        return common("BM-3");
    }

    @Override
    public List<ComponentResult> handlerDM() {
        return common("DM-3");
    }

    @Override
    public List<ComponentResult> handlerBDM() {
        return common("BDM-3");
    }

    /**
     * @auth 佟媛媛
     * @date 18/10/29 下午5:56
     * @desc value相似度匹配
     */
    private ComponentResult common(KVText value,String text,String keyword,String ruleName,String promptMsg,boolean absolute){
        String exist = "02";
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        boolean annotationFlag = true;
        List<ComponentResult.TextPosition> textPositionList = null;
        try{
            if(value!=null){
                annotationFlag = false;
                String _value = value.getText();
                pageNum = value.getPageNumber();
                exist = getSimilar(_value,text,absolute);
                textPositionList = getContentAndPositionList(value);
            }
            return setComponentResult(annotationFlag,exist,keyword,pageNum,promptMsg,ruleName,textPositionList);
        }catch (Exception e){
            log.error(e.getMessage(),e);
            return setComponentResult(annotationFlag,exist,keyword,pageNum,promptMsg,ruleName,textPositionList);
        }
    }

    /**
     * @auth 佟媛媛
     * @date 18/10/29 下午6:03
     * @desc values相似度匹配
     */
    private ComponentResult common(KVText value,List<String> values,String keyword,String ruleName,String promptMsg,boolean absolute){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        List<ComponentResult.TextPosition> textPositionList = null;
        String exist = "02";
        boolean annotationFlag = true;
        try{
            if(value!=null){
                annotationFlag = false;
                String _value = value.getText();
                pageNum = value.getPageNumber();
                if(!StringUtils.isEmpty(_value)){
                    for(String __value : values){
                        if(getSimilar(_value,__value,absolute).equals("01")){
                            exist = "01";break;
                        }else if(getSimilar(_value,__value,absolute).equals("03")){
                            exist = "03";break;
                        }
                    }
                }
                textPositionList = getContentAndPositionList(value);
            }
            return setComponentResult(annotationFlag,exist,keyword,pageNum,promptMsg,ruleName,textPositionList);
        }catch (Exception e){
            log.error(e.getMessage(),e);
            return setComponentResult(annotationFlag,exist,keyword,pageNum,promptMsg,ruleName,textPositionList);
        }

    }

    /**
     * @auth 佟媛媛
     * @date 18/10/29 下午6:01
     * @desc value是否存在
     */
    private ComponentResult common(KVText value,String keyword,String ruleName,String promptMsg){
        List<ComponentResult.TextPosition> textPositionList = null;
        String exist = "02";
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        boolean annotationFlag = true;
        try{
            if(value!=null){
                annotationFlag = false;
                String _value = value.getText();
                pageNum = value.getPageNumber();
                exist = StringUtils.isEmpty(_value)?"02":"01";
                textPositionList = getContentAndPositionList(value);
            }
            return setComponentResult(annotationFlag,exist,keyword,pageNum,promptMsg,ruleName,textPositionList);
        }catch (Exception e){
            log.error(e.getMessage(),e);
            return setComponentResult(annotationFlag,exist,keyword,pageNum,promptMsg,ruleName,textPositionList);
        }
    }

    private ComponentResult setComponentResult(boolean annotationFlag,String exist,String keyword,int pageNum,String promptMsg,String ruleName,List<ComponentResult.TextPosition> textPositionList){
        ComponentResult result = new ComponentResult();
        result.setAnnotationFlag(annotationFlag);
        result.setCatalogId(getCatalogId());
        result.setChapterId(getChapterId());
        result.setExist(exist);
        result.setKeyword(keyword);
        result.setPageNum(pageNum);
        result.setPromptMessage("01".equals(exist)?"正确":promptMsg);
        result.setRegulationId(getRegulationId());
        result.setRuleName(ruleName);
        result.setTextPosition(textPositionList);
        result.setUid(UUID.randomUUID().toString());
        return result;
    }


    /**
     * fxtk.fxdx
     * 发行对象：是否包含“面向全国银行间债券市场的机构投资者（国家法律、法规禁止购买者除外）发行”。
     * "1、检查关键词，不存在提示缺失；2、完全匹配；"
     * 发行阶段
     */
    private ComponentResult fxdx(String tableId,String model,String key){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        if(getKVTextKey(tableId,model,key)==null){
            return setComponentResult(true,"02","主要发行条款-发行对象(是否包含“面向全国银行间债券市场的机构投资者（国家法律、法规禁止购买者除外）发行)",pageNum,"缺失","发行对象",null);
        }
        return common(getKVTextValue(tableId,model,key),
                "面向全国银行间债券市场的机构投资者（国家法律、法规禁止购买者除外）发行","主要发行条款-发行对象(是否包含“面向全国银行间债券市场的机构投资者（国家法律、法规禁止购买者除外）发行)","发行对象","人工核对发行对象", true);
    }
    /**
     * fxtk.cxfs
     * 承销方式：“主承销商、联席主承销商余额包销”或“主承销商、联席主承销商代销”或“主承销商、联席主承销商全额包销”；“主承销商余额包销”或“主承销商代销”或“主承销商全额包销”
     * 1、检查承销方式，满足其中一个即可，若不满足提示核对承销方式；
     * 发行阶段
     */
    private ComponentResult cxfs(String tableId,String model,String key){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        if(getKVTextKey(tableId,model,key)==null){
            return setComponentResult(true,"02","主要发行条款-承销方式(满足主承销商、联席主承销商余额包销等)",pageNum,"缺失","承销方式",null);
        }
        return common(getKVTextValue(tableId,model,key),
                Arrays.asList(new String[]{"主承销商、联席主承销商余额包销","主承销商、联席主承销商代销","主承销商、联席主承销商全额包销","主承销商余额包销","主承销商代销","主承销商全额包销"}),
                "主要发行条款-承销方式(满足主承销商、联席主承销商余额包销等)","承销方式","核对承销方式", false);
    }

    /**
     * fxtk.fxfs
     * 发行方式：“采用集中簿记建档，集中配售方式发行”
     * 1、检查关键词，不存在提示核对发行方式；
     * 发行阶段
     */
    private ComponentResult fxfs(String tableId,String model,String key){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        if(getKVTextKey(tableId,model,key)==null){
            return setComponentResult(true,"02","主要发行条款-发行方式(采用集中簿记建档，集中配售方式发行)",pageNum,"缺失","发行方式",null);
        }
        return common(getKVTextValue(tableId,model,key),"采用集中簿记建档，集中配售方式发行","主要发行条款-发行方式(采用集中簿记建档，集中配售方式发行)","发行方式","核对发行方式",false);
    }
    /**
     * fxtk.dfjg
     * 兑付价格：判断是否填写
     * 1、提示核对兑付价格；
     * 一般为面值兑付，若有其他价格兑付，提示核对兑付价格。
     * 发行阶段
     */
    private ComponentResult dfjg(String tableId,String model,String key){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        if(getKVTextKey(tableId,model,key)==null){
            return setComponentResult(true,"02","主要发行条款-兑付价格(判断是否填写)",pageNum,"缺失","兑付价格",null);
        }
        return common(getKVTextValue(tableId,model,key),"面值兑付","主要发行条款-兑付价格(判断是否填写)","兑付价格","核对兑付价格",true);
    }
    /**
     * fxtk.dffs
     * 兑付方式：判断是否填写
     * 1、提示人工核对兑付方式，不存在提示缺失；
     * 发行阶段
     */
    private ComponentResult dffs(String tableId,String model,String key){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        if(getKVTextKey(tableId,model,key)==null){
            return setComponentResult(true,"02","主要发行条款-兑付方式(判断是否填写)",pageNum,"缺失","兑付方式",null);
        }
        return common(getKVTextValue(tableId,model,key),"主要发行条款-兑付方式(判断是否填写)","兑付方式","核对兑付方式");
    }
    /**
     * fxtk.jzbjjd
     * 集中簿记建档系统技术支持机构：北金所或北京金融资产交易所有限公司
     * 1、检查“集中簿记建档系统技术支持机构”是否为“北金所或北京金融资产交易所有限公司”
     * 发行阶段
     */
    private ComponentResult jzbjjd(String tableId,String model,String key){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        if(getKVTextKey(tableId,model,key)==null){
            return setComponentResult(true,"02","主要发行条款-集中簿记建档系统技术支持机构(是否为“北金所或北京金融资产交易所有限公司”)",pageNum,"缺失","集中簿记建档系统技术支持机构",null);
        }
        return common(getKVTextValue(tableId,model,key),
                Arrays.asList(new String[]{"北金所","北京金融资产交易所有限公司"}),
                "主要发行条款-集中簿记建档系统技术支持机构(是否为“北金所或北京金融资产交易所有限公司”)","集中簿记建档系统技术支持机构","核对集中簿记建档系统技术支持机构", true);
    }
    /**
     * fxtk.xypjjg
     * 信用评级机构：交易商协会官网公布的“评级结果可以在银行间债券市场使用的评级机构名单”为准；把协会官网公布的评级机构建立数据库
     * 1、从M-3-1获取信用评级机构，检查评级机构是否在指定列表中，如果不存在，提示核对评级机构；
     * 预评/发行阶段
     */
    private ComponentResult xypjjg(String tableId,String model,String key){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        if(getKVTextKey(tableId,model,key)==null){
            return setComponentResult(true,"02","主要发行条款-信用评级机构(检查评级机构是否在指定列表中)",pageNum,"缺失","信用评级机构",null);
        }
        List<String> jigous = getOrganization();
        return common(getKVTextValue(tableId,model,key),jigous,"主要发行条款-信用评级机构(检查评级机构是否在指定列表中)","信用评级机构","核对评级机构",false);
    }
    /**
     * fxtk.dbzk
     * 担保状况：提示位置，人工核对
     * "1、检查“担保”关键词是否存在，如果存在提示人工核对，放到疑似正确；2、无担保归类为正确；"
     * 发行阶段
     */
    private ComponentResult dbzk(String tableId,String model,String key){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        if(getKVTextKey(tableId,model,key)==null){
            return setComponentResult(true,"02","主要发行条款-担保状况(条目检查)",pageNum,"缺失","担保状况",null);
        }
        ComponentResult wudanbao = common(getKVTextValue(tableId,model,key),"无担保","主要发行条款-担保状况(条目检查)","担保状况","缺失",true);
        if("01".equals(wudanbao.getExist())){
            return wudanbao;
        }
        ComponentResult danbao = common(getKVTextValue(tableId,model,key),"担保","主要发行条款-担保状况(条目检查)","担保状况","疑似正确",true);
        if("01".equals(danbao.getExist())){
            danbao.setExist("03");
        }
        return danbao;
    }
    /**
     * fxtk.swts
     * 税务提示：提示位置，人工核对
     * 1、检查“根据国家有关法律、法规的规定，投资人投资本期XXX（品种）据所应缴纳的税款由投资人自行承担。”关键词，不存在人工提示；
     * 预评/发行阶段
     */
    private ComponentResult swts(String tableId,String model,String key){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        if(getKVTextKey(tableId,model,key)==null){
            return setComponentResult(true,"02","主要发行条款-税务提示",pageNum,"缺失","税务提示",null);
        }
        List<String> values = new ArrayList<>();
        List<String> pinzhongs = getVarieties();
        for(String pinzhong : pinzhongs){
            values.add("根据国家有关法律、法规的规定，投资人投资本期"+pinzhong+"（品种）据所应缴纳的税款由投资人自行承担");
        }
        return common(getKVTextValue(tableId,model,key),"根据国家有关法律、法规的规定，投资人投资本期据所应缴纳的税款由投资人自行承担","主要发行条款-税务提示","税务提示","核对税务提示",false);
    }
    /**
     * fxtk.syfl
     * 适用法律：提示位置，人工核对
     * 1、检查“根据国家有关法律、法规的规定，投资人投资本期XXX（品种）据所应缴纳的税款由投资人自行承担。”键词，不存在人工提示；
     * 预评/发行阶段
     */
    private ComponentResult syfl(String tableId,String model,String key){
        int pageNum = getChapterModel(getCatalogId()).getStartPage();
        if(getKVTextKey(tableId,model,key)==null){
            return setComponentResult(true,"02","主要发行条款-适用法律",pageNum,"缺失","适用法律",null);
        }
        List<String> values = new ArrayList<>();
        List<String> pinzhongs = getVarieties();
        for(String pinzhong : pinzhongs){
            values.add("本期所发行"+pinzhong+"（品种）的所有法律条款均适用中华人民共和国法律");
        }
        return common(getKVTextValue(tableId,model,key),"本期所发行的所有法律条款均适用中华人民共和国法律","主要发行条款-适用法律","适用法律","核对适用法律",false);
    }

    /**
     * @auth 佟媛媛
     * @date 18/10/29 下午6:23
     */
    private List<String> getVarieties(){
        return Arrays.asList(new String[]{});
    }

    /**
     * @auth 佟媛媛
     * @date 18/10/30 下午1:22
     * @desc  机构列表
     */
    private List<String> getOrganization(){
        return QYZXUtils.getDefaultXypjjg();
    }





    private String getSimilar(String text1,String text2,boolean absolute){
        if(absolute){//是否绝对匹配
            if(stringFilter(text1).contains(stringFilter(text2)) || stringFilter(text2).contains(stringFilter(text1))){
                return "01";
            }else{
                return "02";
            }
        }else{
            double d = SimilarAnalyser.getInstance().similarity(text1,text2);
            if(d >= Constants.SEEM_MAX){//正确
                return "01";
            }else if(d < Constants.SEEM_MIN){//错误
                return "02";
            }else{//疑似正确
                return "03";
            }
        }
    }

}
